#pragma once

#include <DrawFunc.h>
#include <xmemdc.h>


class CXStrButton : public CWindowImpl<CXStrButton>
{
public:
	CXStrButton():m_nButtonTypeCount(0), m_nButtonState(BUTTON_NORMAL), 
		m_bMouseLeave(FALSE), m_bButtonDown(FALSE)
	{
		m_color[BUTTON_NORMAL]	= RGB(0, 0, 0);
		m_color[BUTTON_HOVER]	= RGB(0, 0, 0);
		m_color[BUTTON_PUSHED]	= RGB(0, 0, 0);
		m_color[BUTTON_DISABLE] = RGB(0, 0, 0);
	}
	BEGIN_MSG_MAP_EX(CXStrButton)
		MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
		MSG_WM_LBUTTONDOWN(OnLButtonDown)
		MSG_WM_LBUTTONUP(OnLButtonUp)
		MSG_WM_PAINT(OnPaint)
		MSG_WM_ERASEBKGND(OnEraseBkgnd)
		MSG_WM_MOUSEMOVE(OnMouseMove)
		MSG_WM_MOUSELEAVE(OnMouseLeave)
	END_MSG_MAP()

	BOOL SubclassWindow(HWND hWnd)
	{
		HWND a = m_hWnd;
		BOOL bRet = CWindowImpl::SubclassWindow(hWnd);
		if(bRet)
			Init();
		return bRet;
	}

	void Init()
	{
		//	ModifyStyle(0, BS_OWNERDRAW);
		// create a tool tip
		m_tooltip.Create(m_hWnd);
		//	m_tooltip.ModifyStyle(0, TTS_ALWAYSTIP);
		ATLASSERT(m_tooltip.IsWindow());
		if(m_tooltip.IsWindow() && !m_strToolTip.IsEmpty())
		{
			m_tooltip.Activate(TRUE);	
			m_tooltip.AddTool(m_hWnd, (LPTSTR)(LPCTSTR)m_strToolTip);
		}
	}
	/*********   command ****************/
	LRESULT OnEraseBkgnd(HDC)
	{
		return TRUE;
	}
	LRESULT OnPaint(HDC hdc)
	{
		CPaintDC dc(m_hWnd);
		CRect rect;
		GetClientRect(&rect);

		CXMemDC memDC(dc.m_hDC, rect);

		CWindow parentWnd = GetParent();
		CRect parentRect(rect);
		ClientToScreen(parentRect);
		parentWnd.ScreenToClient(&parentRect);

		HDC parentDC = ::GetDC(parentWnd.m_hWnd);	
		::BitBlt(memDC.m_hDC, 0, 0,  parentRect.Width(), parentRect.Height(), parentDC, parentRect.left, parentRect.top, SRCCOPY);
		ReleaseDC(parentDC);

		if (!m_strText.IsEmpty())
		{
			DrawMyText(memDC.m_hDC, m_strText, rect, m_color[m_nButtonState], DT_CENTER | DT_SINGLELINE | DT_VCENTER, m_nTextFormat);
		}

		return 0;
	}

	LRESULT OnMouseMove(WPARAM wParam, CPoint pt)
	{
		if (!m_bMouseLeave)
		{
			TRACKMOUSEEVENT mouseevent = {0};
			mouseevent.cbSize = sizeof(TRACKMOUSEEVENT);
			mouseevent.dwFlags = TME_LEAVE;
			mouseevent.hwndTrack = m_hWnd;
			::TrackMouseEvent(&mouseevent);

			m_bMouseLeave = TRUE;
		}
		if (m_bButtonDown)
		{
			return 0;
		}
		if (m_nButtonState != BUTTON_HOVER)
		{
			m_nButtonState = BUTTON_HOVER;
			Invalidate(FALSE);
		}
		::PostMessage(GetParent(), WM_MOUSEMOVE, wParam, MAKELPARAM( pt.x, pt.y ));
		return 1;
	}

	LRESULT OnMouseLeave()
	{
		m_bMouseLeave = FALSE;
		m_bButtonDown = FALSE;
		if (m_nButtonState != BUTTON_NORMAL)
		{
			m_nButtonState = BUTTON_NORMAL;
			Invalidate(FALSE);
		}
		CPoint pt;
		GetCursorPos(&pt);
		HWND hParent = GetParent();
		::PostMessage(hParent, WM_MOUSEMOVE, NULL, MAKELPARAM(pt.x, pt.y));
		return 0;
	}

	LRESULT OnLButtonDown(WPARAM wParam, CPoint pt)
	{
		m_bButtonDown = TRUE;
		if (m_nButtonState != BUTTON_PUSHED)
		{
			m_nButtonState = BUTTON_PUSHED;
			Invalidate(FALSE);
		}
		return 0;
	}

	LRESULT OnLButtonUp(WPARAM wParam, CPoint pt)
	{
		if (m_bButtonDown)
		{
			int nID = GetDlgCtrlID();
			::PostMessage(GetParent(), WM_COMMAND, nID, 0);	
		}
		m_bButtonDown = FALSE;
		if (m_nButtonState != BUTTON_HOVER)
		{
			m_nButtonState = BUTTON_HOVER;
			Invalidate(FALSE);
		}
		return 0;
	}
	LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		MSG msg = { m_hWnd, uMsg, wParam, lParam };
		if(m_tooltip.IsWindow())
			m_tooltip.RelayEvent(&msg);
		bHandled = FALSE;
		return 1;

	}
	/*********   function ****************/

	void SetTooltip(const CString & str)
	{
		m_strToolTip = str;
		if(m_strToolTip.IsEmpty())
		{
			if(m_tooltip.IsWindow())
				m_tooltip.Activate(FALSE);
			return;
		}

		if(m_tooltip.IsWindow())
		{
			m_tooltip.Activate(TRUE);	
			m_tooltip.AddTool(m_hWnd, (LPTSTR)(LPCTSTR)m_strToolTip);

		}
	}

	void SetText(const CString & str){m_strText = str;};
	void SetColor(COLORREF col1, COLORREF col2, COLORREF col3 = RGB(0,0,0), COLORREF col4 = RGB(0,0,0))
	{
		m_color[BUTTON_NORMAL]	= col1;
		m_color[BUTTON_HOVER]	= col2;
		m_color[BUTTON_PUSHED]	= col3;
		m_color[BUTTON_DISABLE] = col4;
	}
	void SetFormat(int nFormat){
		m_nTextFormat = nFormat;
	}

private:
	int				m_nButtonState;
	CString			m_strText;
	int				m_nButtonTypeCount;
	CRect			m_rcClient;

	BOOL			m_bMouseLeave;
	BOOL			m_bButtonDown;

	CToolTipCtrl	m_tooltip;
	CString			m_strToolTip;
	COLORREF		m_color[BUTTON_TOTAL];
	int				m_nTextFormat;
};